package 牛客.树;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/*
 * @Author   helen
 * @Date     2021/4/15 15:01
 * @Descriptions
 * 题目描述
    给定一棵二叉树，已经其中没有重复值的节点，请判断该二叉树是否为搜索二叉树和完全二叉树。
    示例1
    输入    {2,1,3}
    返回值  [true,true]
 */
public class 判断搜索二叉树和完全二叉树 {



    public boolean[] judgeIt (BTreeNode<Integer> root) {
        // write code here
        boolean[] result = {true,true};
        if(root == null)
            return result;

        //判断搜索二叉树  使用中序遍历搜索判断
        Stack<BTreeNode<Integer>> stack = new Stack<>();
        ArrayList<Integer> list = new ArrayList<>();
        BTreeNode<Integer> cur = root;
        while(!stack.isEmpty()){
            if(cur != null){
                stack.push(cur);
                cur = cur.left;
            }else {
                cur = stack.pop();
                list.add(cur.data);
                cur = cur.right;
            }
        }
        for (int i = 1; i < list.size(); i++) {
            if(list.get(i) < list.get(i - 1)){
                result[0] = false;
                break;
            }
        }

        //判断完全二叉树
        Queue<BTreeNode<Integer>> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()){
            BTreeNode<Integer> node = queue.peek();
            //2.1如果该节点两个孩子都有，则直接poll，然后把左右结点入队
            if(node.left != null && node.right != null){
                queue.poll();
                queue.add(node.left);
                queue.add((node.right));
            }
            //2.2如果该节点左孩子为空，右孩子不为空，则一定不是完全二叉树
            if(node.left == null && node.right != null) {
                result[1] = false;
                break;
            }
            //2.3如果该节点左孩子不为空，右孩子为空 或者 左右孩子均为空，
            // 则该节点之后的所有结点均为叶子结点，把叶子结点直接poll出来
            if((node.left != null && node.right == null) || (node.left == null && node.right == null)){
                if(node.left != null && node.right == null)
                    queue.add(node.left);
                queue.poll();
                while (!queue.isEmpty()){
                    node = queue.peek();
                    //到此，如果还存在不是叶子结点的结点的话，则不是完全二叉树
                    if(node.left == null && node.right == null)
                        queue.poll();
                    else {
                        result[1] = false;
                        break;
                    }
                }
            }
        }
        return result;

    }

    public static void main(String[] args) {
        判断搜索二叉树和完全二叉树 obj = new 判断搜索二叉树和完全二叉树();
        BTree<Integer> tree =  new BTree<>();
        for (int i = 0; i < 10; i++) {
            tree.RandomCreatTree(tree.root, i);
        }
        final boolean[] booleans = obj.judgeIt(tree.root);
        System.out.println(booleans[0] + " " + booleans[1]);
    }

}
